package com.right.near.business.service.impl;

import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.right.near.business.entity.User;
import com.right.near.business.mapper.UserMapper;
import com.right.near.business.model.ao.*;
import com.right.near.business.model.vo.UserAddVO;
import com.right.near.business.model.vo.UserExcelVO;
import com.right.near.business.model.vo.UserInfoVO;
import com.right.near.business.model.vo.UserVO;
import com.right.near.business.service.IUserService;
import com.right.near.common.constants.NumberConstants;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.ServletOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 用户服务实现类
 *
 * @author star
 * @since 2022-07-20
 */
@Slf4j
@Service
@AllArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    /**
     * 用户分页查询
     *
     * @param ao 请求参数
     * @return Page<UserVO> 响应参数
     */
    @Override
    public Page<UserVO> queryUserPage(UserPageAO ao) {
        return baseMapper.queryUserPage(ao.createPage(), ao);
    }

    /**
     * 用户明细查询
     *
     * @param ao 请求参数
     * @return UserInfoVO 响应参数
     */
    @Override
    public UserInfoVO queryUserDetail(UserInfoAO ao) {
        User user = super.getById(ao.getId());
        if (Objects.nonNull(user)) {
            UserInfoVO vo = new UserInfoVO();
            BeanUtils.copyProperties(user, vo);
            return vo;
        }
        return null;
    }

    /**
     * 用户新增数据
     *
     * @param ao 请求参数
     * @return UserAddVO 响应参数
     */
    @Override
    public UserAddVO addUser(UserAddAO ao) {
        User entity = new User();
        BeanUtils.copyProperties(ao, entity);
        super.save(entity);
        UserAddVO vo = new UserAddVO();
        vo.setId(entity.getId());
        return vo;
    }

    /**
     * 用户修改数据
     *
     * @param ao 数据
     */
    @Override
    public void updateUser(UserUpdateAO ao) {
        User entity = new User();
        BeanUtils.copyProperties(ao, entity);
        super.updateById(entity);
    }

    /**
     * 用户删除数据
     *
     * @param ao 请求参数
     */
    @Override
    public void deleteUser(UserDeleteAO ao) {
        User entity = new User();
        entity.setId(ao.getId());
        super.updateById(entity);
    }

    /**
     * 用户批量删除数据
     *
     * @param aos 请求参数
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteBatchUser(List<UserDeleteAO> aos) {
        for (UserDeleteAO ao : aos) {
            deleteUser(ao);
        }
    }

    /**
     * 用户导出数据
     *
     * @param ao     请求参数
     * @param stream 输出流
     */
    @Override
    public void exportUser(UserPageAO ao, ServletOutputStream stream) {
        ao.setSize(-1);
        List<UserVO> vos = queryUserPage(ao).getRecords();
        List<UserExcelVO> list = new ArrayList<>(vos.size());
        for (UserVO vo : vos) {
            UserExcelVO excelVo = new UserExcelVO();
            BeanUtils.copyProperties(vo, excelVo);
            list.add(excelVo);
        }

        ExcelWriter excelWriter = EasyExcelFactory.write(stream).build();
        excelWriter.write(list, EasyExcelFactory.writerSheet(NumberConstants.ZERO, "用户").head(UserExcelVO.class).build());
        excelWriter.finish();
    }

    /**
     * 根据用户名称查询用户信息
     *
     * @param userName 用户名称
     * @return User
     */
    @Override
    public User queryUserByUserName(String userName) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(User::getIsDeleted, NumberConstants.ZERO)
                .eq(User::getUserName, userName);
        return baseMapper.selectOne(queryWrapper);
    }

}